package com.mdinic.blogovi.front.page.addblogpost;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.util.ListModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.validation.validator.UrlValidator;

import com.mdinic.blogovi.front.common.AbstractFormFeedbackPanel;
import com.mdinic.blogovi.front.page.BSession;
import com.mdinic.blogovi.front.page.HomePage;
import com.mdinic.blogovi.model.BlogPost;
import com.mdinic.blogovi.model.BlogType;
import com.mdinic.blogovi.service.BlogPostService;
import com.mdinic.blogovi.service.model.BlogPostResult;

public class AddBlogPostPanel extends AbstractFormFeedbackPanel<BlogPost> {

    private static final Model<String> DESC_LEN_OK = new Model<String>("blog-description-len-ok");

    private static final Model<String> DESC_LEN_INVALID = new Model<String>("blog-description-len-fail");

    @SpringBean
    private BlogPostService blogPostService;

    private static final long serialVersionUID = 1L;

    private Integer descriptionLen = 0;

    public AddBlogPostPanel() {
        super(ID, new BlogPost());

        final Label descriptionLenLabel = new Label("description_len", new PropertyModel<Integer>(this,
                "descriptionLen"));

        descriptionLenLabel.setOutputMarkupId(true);
        final TextField<String> url = new TextField<String>(BlogPost.URL);
        url.add(new UrlValidator());
        getForm().add(url.setRequired(true));

        final TextField<String> headline = new TextField<String>(BlogPost.HEADLINE);
        final TextArea<String> textArea = new TextArea<String>(BlogPost.DESCRIPTION);
        final DropDownChoice<BlogType> typeDDC = new DropDownChoice<BlogType>(BlogPost.TYPE, new ListModel<BlogType>() {

            private static final long serialVersionUID = 1L;

            @Override
            public List<BlogType> getObject() {
                return blogPostService.getBlogTypes();
            }

        });

        headline.setOutputMarkupId(true);
        textArea.setOutputMarkupId(true);
        typeDDC.setOutputMarkupId(true);
        AjaxButton loadTitleButton = new AjaxButton("loadTitle") {

            private static final long serialVersionUID = 1L;

            @Override
            protected void onError(AjaxRequestTarget target, Form<?> form) {
                super.onError(target, form);
                target.add(getFeedbackPanel());
            }

            @Override
            protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                target.add(getFeedbackPanel());
                String title = blogPostService.getTitle(url.getModelObject());
                headline.setModelObject(title);
                headline.setEnabled(true);
                textArea.setEnabled(true);
                typeDDC.setEnabled(true);

                target.add(headline);
                target.add(textArea);
                target.add(typeDDC);

                if (title.equals(StringUtils.EMPTY)) {
                    target.focusComponent(headline);
                } else {
                    target.focusComponent(textArea);
                }
            }
        };

        headline.setEnabled(false);
        textArea.setEnabled(false);
        typeDDC.setEnabled(false);
        headline.setRequired(true);

        textArea.add(new AjaxFormComponentUpdatingBehavior("onkeyup inputchange change") {

            private static final long serialVersionUID = 1L;

            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                if (textArea.getModelObject() == null) {
                    descriptionLen = 0;
                } else {
                    descriptionLen = textArea.getModelObject().length();
                }
                if (descriptionLen < 20 || descriptionLen > 500) {
                    descriptionLenLabel.add(new AttributeModifier("class", DESC_LEN_INVALID));
                } else {
                    descriptionLenLabel.add(new AttributeModifier("class", DESC_LEN_OK));
                }
                target.add(descriptionLenLabel);
            }

        });

        getForm().add(headline);
        getForm().add(loadTitleButton);
        getForm().add(descriptionLenLabel);
        getForm().add(textArea);
        getForm().add(typeDDC);
    }

    @Override
    protected void submit(BlogPost blogPost) {

        if (descriptionLen < 20 || descriptionLen > 500) {
            error("Opis mora biti od 20 do 500 karaktera.");
            return;
        }

        if (blogPost.getType() == null) {
            error("Tip je obavezan.");
            return;
        }

        blogPost.setPerson(BSession.get().getPerson());

        BlogPostResult post = blogPostService.post(blogPost);
        switch (post.getType()) {
        case OK:

            setResponsePage(HomePage.class);
            break;
        case EXISTING:
            error("Blog post vec postoji u sistemu");
            // TODO set link to existing post
            break;

        case BLACKLISTED:
            error("Zao nam je ali blog je na list nedozvoljenih.");
            break;
        default:
            throw new IllegalStateException("State is not supported " + post.getType());
        }

    }
}
